home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_023 / ver30 / tty / termcap / tty.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  7KB  |  333 lines

  1. /*
  2.  * Name:    MicroEMACS
  3.  *        UNIX termcap/terminfo display driver
  4.  * Version:    2
  5.  * Last edit:    16-Apr-86
  6.  * By:        paul@ohio-state
  7.  *        cbosgd!osu-eddie!paul
  8.  *
  9.  * Termcap is a terminal information database and routines to describe 
  10.  * terminals on a UNIX system.  This should be used ALLWAYS on a UNIX system
  11.  * that has it.
  12.  */
  13. #include    "def.h"
  14.  
  15. #define    BEL    0x07            /* BEL character.        */
  16. #define    ESC    0x1B            /* ESC character.        */
  17. #define    LF    0x0A            /* Line feed.            */
  18.  
  19. extern    int    ttrow;
  20. extern    int    ttcol;
  21. extern    int    tttop;
  22. extern    int    ttbot;
  23. extern    int    tthue;
  24.  
  25. int    tceeol;            /* Costs are set later */
  26. int    tcinsl;
  27. int    tcdell;
  28.  
  29. #define TCAPSLEN 315
  30.  
  31. char tcapbuf[TCAPSLEN];
  32. char    PC,
  33.         *CM,
  34.         *CL,
  35.         *CE,
  36.         *UP,
  37.     *IM,            /* insert mode */
  38.     *IC,            /* insert a single space */
  39.     *EI,            /* end insert mode */
  40.     *DC,
  41.     *AL,            /* add line */
  42.     *DL,            /* del line */
  43.     *TI,            /* term init -- start using cursor motion */
  44.     *TE,            /* term end --- end using cursor motion */
  45.     *SO,
  46.     *SE,
  47.         *CD;
  48.  
  49. /*
  50.  * Initialize the terminal when the editor
  51.  * gets started up. This is a no-op on the ANSI
  52.  * display. On the SCALD display, it turns off the
  53.  * half-screen scroll, because this appears to really
  54.  * confuse the scrolling region firmware in the
  55.  * display.
  56.  */
  57. static char tcbuf[1024];
  58.  
  59. ttinit()
  60. {
  61.         char *getenv();
  62.         char *t, *p, *tgetstr();
  63.         char *tv_stype;
  64.         char err_str[72];
  65.  
  66.         if ((tv_stype = getenv("TERM")) == NULL)
  67.         {
  68.                 puts("Environment variable TERM not defined!");
  69.                 exit(1);
  70.         }
  71.  
  72.         if((tgetent(tcbuf, tv_stype)) != 1)
  73.         {
  74.                 sprintf(err_str, "Unknown terminal type %s!", tv_stype);
  75.                 puts(err_str);
  76.                 exit(1);
  77.         }
  78.  
  79.         p = tcapbuf;
  80.         t = tgetstr("pc", &p);
  81.         if(t)
  82.                 PC = *t;
  83.  
  84.         CD = tgetstr("cd", &p);
  85.         CM = tgetstr("cm", &p);
  86.         CE = tgetstr("ce", &p);
  87.         UP = tgetstr("up", &p);
  88.     IM = tgetstr("im", &p);
  89.     IC = tgetstr("ic", &p);
  90.     EI = tgetstr("ei", &p);
  91.     DC = tgetstr("dc", &p);
  92.     AL = tgetstr("al", &p);
  93.     DL = tgetstr("dl", &p);
  94.     TI = tgetstr("ti", &p);
  95.     TE = tgetstr("te", &p);
  96.     SO = tgetstr("so", &p);
  97.     SE = tgetstr("se", &p);
  98.  
  99.         if(CD == NULL || CM == NULL || CE == NULL || UP == NULL)
  100.         {
  101.                 puts("This terminal is not powerful enough to run Micro Emacs\n");
  102.                 exit(1);
  103.         }
  104.     if (!*CE) {
  105.         tceeol = ncol;
  106.     } else {
  107.         tceeol = charcost(CE);
  108.     }
  109.     if (AL == NULL || !*AL) {
  110.         tcinsl = nrow * ncol; /* make this cost high enough that it */
  111.                   /* won't ever happen */
  112.     } else {
  113.         tcinsl = charcost(AL);
  114.     }
  115.     if (DL == NULL || !*DL) {
  116.         tcdell = nrow * ncol; /* make this cost high enough that it */
  117.                   /* won't ever happen */
  118.     } else {
  119.         tcdell = charcost(DL);
  120.     }
  121.  
  122.         if (p >= &tcapbuf[TCAPSLEN])
  123.         {
  124.                 puts("Terminal description too big!\n");
  125.                 exit(1);
  126.         }
  127.     if (TI != NULL && *TI) tputs (TI);    /* init the term */
  128. }
  129.  
  130. /*
  131.  * Clean up the terminal, in anticipation of
  132.  * a return to the command interpreter. This is a no-op
  133.  * on the ANSI display. On the SCALD display, it sets the
  134.  * window back to half screen scrolling. Perhaps it should
  135.  * query the display for the increment, and put it
  136.  * back to what it was.
  137.  */
  138. tttidy()
  139. {
  140.     if (TE != NULL && *TE) tputs (TE);    /* set the term back to normal mode */
  141. }
  142.  
  143. /*
  144.  * Move the cursor to the specified
  145.  * origin 0 row and column position. Try to
  146.  * optimize out extra moves; redisplay may
  147.  * have left the cursor in the right
  148.  * location last time!
  149.  */
  150. ttmove(row, col)
  151. {
  152.     if (ttrow!=row || ttcol!=col) {
  153.     putpad(tgoto(CM, col, row));
  154.     ttrow = row;
  155.     ttcol = col;
  156.     }
  157. }
  158.  
  159. /*
  160.  * Erase to end of line.
  161.  */
  162. tteeol()
  163. {
  164.         putpad(CE);
  165. }
  166.  
  167. /*
  168.  * Erase to end of page.
  169.  */
  170. tteeop()
  171. {
  172.         putpad(CD);
  173. }
  174.  
  175. /*
  176.  * Make a noise.
  177.  */
  178. ttbeep()
  179. {
  180.     ttputc(BEL);
  181.     ttflush();
  182. }
  183.  
  184. /*
  185.  * Insert nchunk blank line(s) onto the
  186.  * screen, scrolling the last line on the
  187.  * screen off the bottom. This is done with
  188.  * a cluster of clever insert and delete commands,
  189.  * because there are no scroll regions.
  190.  */
  191. ttinsl(row, bot, nchunk)
  192. {
  193.     register int    i;
  194.     
  195.     if (row == bot) {        /* Case of one line insert is     */
  196.     ttmove(row, 0);        /*    special            */
  197.     tteeol();
  198.     return;
  199.     }
  200.     ttmove(1+bot-nchunk, 0);
  201.     for (i=0; i<nchunk; i++) {    /* For all lines in the chunk    */
  202.     putpad(DL);
  203.     }
  204.     ttmove(row, 0);
  205.     for (i=0; i<nchunk; i++) {    /* For all lines in the chunk    */
  206.     putpad(AL);
  207.     }
  208.     ttrow = row;            /* End up on current line    */
  209.     ttcol = 0;
  210. }
  211.  
  212. /*
  213.  * Delete nchunk line(s) "row", replacing the
  214.  * bottom line on the screen with a blank
  215.  * line. This is done with a crafty sequences
  216.  * of insert and delete line; We assume that the terminal
  217.  * is like the Heath (ie no scrolling region). The presence of the
  218.  * echo area makes a boundry condition
  219.  * go away.
  220.  */
  221. ttdell(row, bot, nchunk)
  222. {
  223.     register int    i;
  224.     
  225.     if (row == bot) {        /* One line special case    */
  226.     ttmove(row, 0);
  227.     tteeol();
  228.     return;
  229.     }
  230.     ttmove(row, 0);
  231.     for (i=0; i<nchunk; i++) {    /* For all lines in chunk    */
  232.     putpad(DL);
  233.     }
  234.     ttmove(1+bot-nchunk,0);
  235.     for (i=0; i<nchunk; i++) {    /* For all lines in chunk    */
  236.     putpad(AL);
  237.     }
  238.     ttrow = bot-nchunk;
  239.     ttcol = 0;
  240. }
  241.  
  242. /*
  243.  * No-op.
  244.  */
  245. ttwindow(top, bot)
  246. {
  247. }
  248.  
  249. /*
  250.  * No-op.
  251.  */
  252. ttnowindow()
  253. {
  254. }
  255.  
  256. /*
  257.  * Set the current writing color to the
  258.  * specified color. Watch for color changes that are
  259.  * not going to do anything (the color is already right)
  260.  * and don't send anything to the display.
  261.  * The rainbow version does this in putline.s on a
  262.  * line by line basis, so don't bother sending
  263.  * out the color shift.
  264.  */
  265. ttcolor(color)
  266. register int    color;
  267. {
  268.     if (color != tthue) {
  269.     if (color == CTEXT) {        /* Normal video.    */
  270.         putpad(SE);
  271.     } else if (color == CMODE) {    /* Reverse video.    */
  272.         putpad(SO);
  273.     }
  274.     tthue = color;            /* Save the color.    */
  275.     }
  276. }
  277.  
  278. /*
  279.  * This routine is called by the
  280.  * "refresh the screen" command to try and resize
  281.  * the display. The new size, which must be deadstopped
  282.  * to not exceed the NROW and NCOL limits, it stored
  283.  * back into "nrow" and "ncol". Display can always deal
  284.  * with a screen NROW by NCOL. Look in "window.c" to
  285.  * see how the caller deals with a change.
  286.  */
  287. ttresize()
  288. {
  289.     register int    c;
  290.     register int    newnrow;
  291.     register int    newncol;
  292.  
  293.     newnrow = tgetnum("li"); /* on a Sun, this returns the NEW size */
  294.     newncol = tgetnum("co"); /* on anything else, returns same old size */
  295.  
  296.     if (newnrow < 1)            /* Check limits.    */
  297.         newnrow = 1;
  298.     else if (newnrow > NROW)
  299.         newnrow = NROW;
  300.     if (newncol < 1)
  301.         newncol = 1;
  302.     else if (newncol > NCOL)
  303.         newncol = NCOL;
  304.     nrow = newnrow;
  305.     ncol = newncol;
  306. }
  307.  
  308. static int cci;
  309.  
  310. static
  311. fakec(c)            /* fake char output for charcost() */
  312. char c;
  313. {
  314.     cci++;
  315. }
  316.  
  317. charcost (s)            /* calculate the cost of doing string s */
  318. char *s;
  319. {
  320.     cci = 0;
  321.  
  322.     tputs(s, nrow, fakec);
  323.     return cci;
  324. }
  325.  
  326. putpad(str)
  327. char    *str;
  328. {
  329.         tputs(str, 1, ttputc);
  330. }
  331.  
  332.  
  333.